#!/usr/bin/env python
"""Server module for hosting multiplayer games"""
import os, sys, random, pygame, getopt, signal
import game, vecmath, camera, particles, net, vessels, ai, gl
from vessels import *
from pygame.locals import *

FPS = 30.0
F_DELTA = FPS / 1000.0 # to calculate time-based deltas
clock = None
_running = 1
_jit = 1 # flag to enable jit via psyco
_profile = 0 # flag to enable profiling via hotshot
_bots_cylons = 0 # number of cylons controlled by ia
_bots_humans = 0 # number of humans controller by ia
_port = 1337
_protocol = None

def empty_stub(*args):
    pass

def p(x):
    print x

def startup():
    """Inites the game to a initial state
    Creates the display and populates the 'game' objects"""
    game.debug = p
    game.ships = gl.GLGroup()
    game.bullets = gl.GLGroup()
    game.stars = gl.GLGroup()
    game.dimensions = Rect((0, 0), (0, 0))
    
    # cripple particle system
    game.particles = particles.ParticleSystem(0)
    game.particles.update = empty_stub
    
    # creater a crippled version of the camera, still functional but useless
    game.cam = camera.Camera()
    game.cam.speed = lambda: (0, 0)
    game.cam.position = lambda: (0, 0)
    game.cam.update = empty_stub
    game.cam.check_distance = empty_stub
    
    # dont let ships update their image
    print _bots_humans, _bots_cylons
    for i in xrange(_bots_humans):
        e = colonial.Viper(ai.Simple)
        e.position = [1000 + random.random() * 1000, 1000 + random.random() * 1000]
        game.ships.add(e)
        
    for i in xrange(_bots_cylons):
        e = cylon.Raider(ai.Simple)
        e.position = [-1000 + random.random() * -1000, -1000 + random.random() * -1000]
        game.ships.add(e)
    
    _protocol.start()

def main_loop():
    """Will iterate while _running is true,
    processing events, drawing and updating the game state"""
    print "=" * 60
    print 'Starting game'
    print 'ships:'
    for s in game.ships:
        print s.__class__.__name__ + ' - ' + str(s.id) + ' @' + str(s.position)
    print "=" * 60
    while(_running):
        delta = clock.tick(FPS) * F_DELTA
        game.delta = delta
        _protocol.update()
        game.update_groups(delta)

def run_profile():
    """Performs a full profile of the application"""
    import hotshot, hotshot.stats, test.pystone
    prof = hotshot.Profile("pyship.prof") # file to store the results
    benchtime = prof.run('main_loop()') # run the method
    prof.close() # done
    stats = hotshot.stats.load("pyship.prof") # load the results
    stats.strip_dirs() 
    stats.sort_stats('time', 'calls') # sort by time invested on each method
    stats.print_stats(20)
    
def usage():
    print '''Usage: python main.py [options]
    Options:
        -h, --help: Shows this message
        -f, --profile: Runs the game through a profiler and shows the results on
                       exit
        -n, --no-optimize: Skips the jit compilation with psyco (use if you have
                           problems running psyco)
        -c N, --cylons=N: Number of cylon bots to add to the game
        -l N, --colonials=N: Number of colonial bots to add to the game
	-p port, --server-port=port: starts the dedicated server in the given port'''
    sys.exit(0)

def term():
    global _running
    _running = 0

if (__name__ ==  '__main__'):
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hfnc:l:p:",\
                                   ["help", "profile", "no-optimize",\
                                    "cylons=", "colonials=", "play-as=",\
                                    "fullscreen", "screen-size="])
    except getopt.GetoptError:
        print 'Opciones no reconocidas'
        usage()
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage()
        elif opt in ('-f', '--profile'):
            _profile = 1
        elif opt in ('-n', '--no-optimize'):
            _jit = 0
        elif opt in ('-l', '--colonials'):
            _bots_humans = int(arg)
        elif opt in ('-c', '--cylons'):
            _bots_cylons = int(arg)
        elif opt in ('-p', '--server-port'):
            _port = arg
    
    if _jit:
        try:
            import psyco
            psyco.log()
            psyco.bind(main_loop)
            psyco.bind(pygame.sprite.spritecollideany)
            psyco.profile()
        except ImportError, message:
            print message

    pygame.init()
    
    clock = pygame.time.Clock()
    
    _protocol = net.ServerProtocol(_port)
    
    startup()
    

    if _profile:
        run_profile()
    else:
        main_loop()

